//
//  squares_matrix.c
//  linear_algebra
//
//  Created by zhangnan on 2025/3/27.
//

#include "squares_matrix.h"
#include <stdlib.h>

/**
 * 创建一个指定阶数的双精度浮点数矩阵
 * @param order 矩阵的阶数
 * @return 返回创建的矩阵指针，如果内存分配失败则返回NULL
 */
SQUARES_DOUBLE_MATRIX_TYPE* create_squares_double_matrix(int order)
{
    // 分配矩阵结构体的内存
    SQUARES_DOUBLE_MATRIX_TYPE *matrix = (SQUARES_DOUBLE_MATRIX_TYPE*)malloc(sizeof(SQUARES_DOUBLE_MATRIX_TYPE));
    if (matrix == NULL) {
        return NULL;
    }
    // 分配矩阵元素数组的内存
    matrix->array = (double*)malloc(sizeof(double)*order*order);
    if (matrix->array == NULL) {
        free(matrix);
        return NULL;
    }
    matrix->order = order;

    return matrix;
}

/**
 * 创建一个指定阶数的整数矩阵
 * @param order 矩阵的阶数
 * @return 返回创建的矩阵指针，如果内存分配失败则返回NULL
 */
SQUARES_INT_MATRIX_TYPE* create_squares_int_matrix(int order)
{
    // 分配矩阵结构体的内存
    SQUARES_INT_MATRIX_TYPE *matrix = (SQUARES_INT_MATRIX_TYPE*)malloc(sizeof(SQUARES_INT_MATRIX_TYPE));
    if (matrix == NULL) {
        return NULL;
    }
    // 分配矩阵元素数组的内存
    matrix->array = (int*)malloc(sizeof(int)*order*order);
    if (matrix->array == NULL) {
        free(matrix);
        return NULL;
    }
    matrix->order = order;
    return matrix;
}

/**
 * 释放双精度浮点数矩阵的内存
 * @param matrix 要释放的矩阵指针
 */
void free_squares_double_matrix(SQUARES_DOUBLE_MATRIX_TYPE *matrix)
{
    // 检查矩阵指针是否为空
    if (matrix != NULL) {
        // 检查矩阵元素数组指针是否为空
        if(matrix->array != NULL){
            free(matrix->array);
        }
        free(matrix);
    }
}

/**
 * 释放整数矩阵的内存
 * @param matrix 要释放的矩阵指针
 */
void free_squares_int_matrix(SQUARES_INT_MATRIX_TYPE *matrix)
{
    // 检查矩阵指针是否为空
    if (matrix != NULL) {
        // 检查矩阵元素数组指针是否为空
        if(matrix->array != NULL){
            free(matrix->array);
        }
        free(matrix);
    }
}

/**
 * 创建并返回一个给定矩阵的子矩阵，子矩阵排除了指定行和列的元素。
 * 此函数针对的是SQUARES_DOUBLE_MATRIX_TYPE类型的矩阵。
 * 
 * @param matrix 指向原始矩阵的指针，基于此矩阵创建子矩阵。
 * @param row_index 指定要从子矩阵中排除的行的索引。
 * @param col_index 指定要从子矩阵中排除的列的索引。
 * @return 返回一个新创建的子矩阵的指针。
 */
SQUARES_DOUBLE_MATRIX_TYPE *create_sub_squares_double_matrix(SQUARES_DOUBLE_MATRIX_TYPE *matrix,int row_index,int col_index)
{
    // 创建一个新矩阵，其阶数比原矩阵少1。
    SQUARES_DOUBLE_MATRIX_TYPE *sub_matrix = create_squares_double_matrix(matrix->order-1);
    int index=0;
    // 遍历原矩阵的所有元素。
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            // 当前元素不属于指定的行或列时，将其添加到子矩阵中。
            if (i != row_index && j != col_index) {
                sub_matrix->array[index]=matrix->array[i*matrix->order+j];
                index++;
            }
        }
    }
    // 返回构建完成的子矩阵。
    return sub_matrix;
}

/**
 * 创建并返回一个给定矩阵的子矩阵，子矩阵排除了指定行和列的元素。
 * 此函数针对的是SQUARES_INT_MATRIX_TYPE类型的矩阵。
 * 
 * @param matrix 指向原始矩阵的指针，基于此矩阵创建子矩阵。
 * @param row_index 指定要从子矩阵中排除的行的索引。
 * @param col_index 指定要从子矩阵中排除的列的索引。
 * @return 返回一个新创建的子矩阵的指针。
 */
SQUARES_INT_MATRIX_TYPE *create_sub_squares_int_matrix(SQUARES_INT_MATRIX_TYPE *matrix,int row_index,int col_index)
{
    // 创建一个新矩阵，其阶数比原矩阵少1。
    SQUARES_INT_MATRIX_TYPE *sub_matrix = create_squares_int_matrix(matrix->order-1);
    int index=0;
    // 遍历原矩阵的所有元素。
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            // 当前元素不属于指定的行或列时，将其添加到子矩阵中。
            if (i != row_index && j != col_index) {
                sub_matrix->array[index]=matrix->array[i*matrix->order+j];
                index++;
            }
        }
    }
    // 返回构建完成的子矩阵。
    return sub_matrix;
}


/**
 * 将方阵的双精度浮点数矩阵转换为双精度浮点数矩阵
 * 
 * @param matrix 指向方阵的双精度浮点数矩阵的指针
 * @return 返回转换后的双精度浮点数矩阵的指针
 */
MATRIX_DOUBLE_TYPE *squares_to_double_matrix(SQUARES_DOUBLE_MATRIX_TYPE *matrix){
    // 创建一个新的双精度浮点数矩阵
    MATRIX_DOUBLE_TYPE *result = create_double_matrix(matrix->order,matrix->order);
    // 遍历方阵的每个元素，并将其复制到新的矩阵中
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            result->array[i*matrix->order+j]=matrix->array[i*matrix->order+j];
        }
    }
    // 释放原始方阵的内存
    free_squares_double_matrix(matrix);
    // 返回新的双精度浮点数矩阵
    return result;
}

/**
 * 将方阵的整数矩阵转换为整数矩阵
 * 
 * @param matrix 指向方阵的整数矩阵的指针
 * @return 返回转换后的整数矩阵的指针
 */
MATRIX_INT_TYPE *squares_to_int_matrix(SQUARES_INT_MATRIX_TYPE *matrix){
    // 创建一个新的整数矩阵
    MATRIX_INT_TYPE *result = create_int_matrix(matrix->order,matrix->order);
    // 遍历方阵的每个元素，并将其复制到新的矩阵中
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            result->array[i*matrix->order+j]=matrix->array[i*matrix->order+j];
        }
    }
    // 释放原始方阵的内存
    free_squares_int_matrix(matrix);
    // 返回新的整数矩阵
    return result;
}